package router

import (
	"errors"
	"github.com/nats-io/go-nats"
	"gopkg/logger"
	"time"
)

type MsgCallback func(remoteServerAddress string, msg []byte)

type NatsRouter struct {
	natConn       *nats.Conn
	msgCB         MsgCallback
	serverAddress string
}

func defaultMsgCallback(remoteServerAddress string, msg []byte) {
	logger.Debug("receive msg %s from %s", string(msg), remoteServerAddress)
}

func ConnectNats(url string, options ...nats.Option) (*NatsRouter, error) {
	conn, err := nats.Connect(url, options...)
	if err != nil {
		return nil, err
	}

	natsRouter := &NatsRouter{
		natConn: conn,
		msgCB:   defaultMsgCallback,
	}
	return natsRouter, nil
}

//设置异步接收数据数据回调
func (self *NatsRouter) SetMsgHandler(cb MsgCallback) {
	self.msgCB = cb
}

//serverAddress 用于接收自己的消息 groupAddress 用于接收发给同类型服务器的数据
func (self *NatsRouter) RegisterServer(serverAddress string, groupAddress ...string) error {

	if serverAddress == "" {
		return errors.New("server address is empty")
	}

	_, err := self.natConn.Subscribe(serverAddress, self.natsMsgHandle)
	if err != nil {
		return err
	}

	if len(groupAddress) > 1 {
		if groupAddress[0] == "" {
			return errors.New("group address is empty")
		}
		_, err := self.natConn.Subscribe(groupAddress[0], self.natsMsgHandle)
		if err != nil {
			return err
		}
	}

	self.serverAddress = serverAddress
	return nil
}

func (self *NatsRouter) natsMsgHandle(msg *nats.Msg) {
	self.msgCB(msg.Reply, msg.Data)
}

//异步发送数据
func (self *NatsRouter) SendMsg(remoteAddress string, msg []byte) error {
	natsMsg := &nats.Msg{}
	natsMsg.Subject = remoteAddress
	natsMsg.Reply = self.serverAddress
	natsMsg.Data = msg
	return self.natConn.PublishMsg(natsMsg)
}

//阻塞请求并获取回应
func (self *NatsRouter) Request(remoteAddress string, data []byte, timeout time.Duration) ([]byte, error) {
	respMsg, err := self.natConn.Request(remoteAddress, data, timeout)
	if err != nil {
		return nil, err
	}
	return respMsg.Data, nil
}

func (self *NatsRouter) Close() {
	self.natConn.Close()
}
